#include "DmMainAfx.h"
#include "Blend.h"

#include <mmintrin.h>
#include <xmmintrin.h>

BOOL xRender::BlendSrcColor32MMX(PBITMAP lpbDst, xARGB x)
{
    LPBYTE lpScanLine = (LPBYTE)lpbDst->bmBits;
    DWORD width = lpbDst->bmWidth;
    __m64 mclr = _m_from_int(x.argb);
    mclr = _m_punpckldq(mclr, mclr);
    for (int j = lpbDst->bmHeight; j > 0; j--)
    {
        LPDWORD lpPixel = (LPDWORD)lpScanLine;
        int i = width >> 3;
        while (i--)
        {
            *(__m64*)lpPixel = mclr;
            *(__m64*)(lpPixel + 2) = mclr;
            *(__m64*)(lpPixel + 4) = mclr;
            *(__m64*)(lpPixel + 6) = mclr;
            lpPixel += 8;
        }
        i = width & 7;
        while (i--)
        {
            *lpPixel = x.argb;
            lpPixel++;
        }
        lpScanLine += lpbDst->bmWidthBytes;
    }
    _m_empty();
    return TRUE;
}

BOOL xRender::BlendOrColor32MMX(PBITMAP lpbDst, xARGB x)
{
    LPBYTE lpScanLine = (LPBYTE)lpbDst->bmBits;
    DWORD width = lpbDst->bmWidth;
    __m64 mclr = _m_from_int(x.argb);
    mclr = _m_punpckldq(mclr, mclr);
    for (int j = lpbDst->bmHeight; j > 0; j--)
    {
        LPDWORD lpPixel = (LPDWORD)lpScanLine;
        int i = width >> 3;
        while (i--)
        {
            *(__m64*)lpPixel = _m_por(*(__m64*)lpPixel, mclr);
            *(__m64*)(lpPixel + 2) = _m_por(*(__m64*)(lpPixel + 2), mclr);
            *(__m64*)(lpPixel + 4) = _m_por(*(__m64*)(lpPixel + 4), mclr);
            *(__m64*)(lpPixel + 6) = _m_por(*(__m64*)(lpPixel + 6), mclr);
            lpPixel += 8;
        }
        i = width & 7;
        while (i--)
        {
            *lpPixel |= x.argb;
            lpPixel++;
        }
        lpScanLine += lpbDst->bmWidthBytes;
    }
    _m_empty();
    return TRUE;
}

BOOL xRender::BlendSrcColor32SSE(PBITMAP lpbDst, xARGB x)
{
    LPBYTE lpScanLine = (LPBYTE)lpbDst->bmBits;
    DWORD width = lpbDst->bmWidth;
    __m64 mclr = _m_from_int(x.argb);
    mclr = _m_punpckldq(mclr, mclr);
    for (int j = lpbDst->bmHeight; j > 0; j--)
    {
        LPDWORD lpPixel = (LPDWORD)lpScanLine;
        int i = width >> 3;
        while (i--)
        {
            _mm_stream_pi((__m64*)lpPixel, mclr);
            _mm_stream_pi((__m64*)(lpPixel + 2), mclr);
            _mm_stream_pi((__m64*)(lpPixel + 4), mclr);
            _mm_stream_pi((__m64*)(lpPixel + 6), mclr);
            lpPixel += 8;
        }
        i = width & 7;
        while (i--)
        {
            *lpPixel = x.argb;
            lpPixel++;
        }
        lpScanLine += lpbDst->bmWidthBytes;
    }
    _mm_sfence();
    _m_empty();
    return TRUE;
}

BOOL xRender::BlendOrColor32SSE(PBITMAP lpbDst, xARGB x)
{
    LPBYTE lpScanLine = (LPBYTE)lpbDst->bmBits;
    DWORD width = lpbDst->bmWidth;
    __m64 mclr = _m_from_int(x.argb);
    mclr = _m_punpckldq(mclr, mclr);
    for (int j = lpbDst->bmHeight; j > 0; j--)
    {
        LPDWORD lpPixel = (LPDWORD)lpScanLine;
        int i = width >> 3;
        while (i--)
        {
            __m64 m0 = _m_por(*(__m64*)lpPixel, mclr);
            __m64 m1 = _m_por(*(__m64*)(lpPixel + 2), mclr);
            __m64 m2 = _m_por(*(__m64*)(lpPixel + 4), mclr);
            __m64 m3 = _m_por(*(__m64*)(lpPixel + 6), mclr);
            _mm_stream_pi((__m64*)lpPixel, m0);
            _mm_stream_pi((__m64*)(lpPixel + 2), m1);
            _mm_stream_pi((__m64*)(lpPixel + 4), m2);
            _mm_stream_pi((__m64*)(lpPixel + 6), m3);
            lpPixel += 8;
        }
        i = width & 7;
        while (i--)
        {
            *lpPixel |= x.argb;
            lpPixel++;
        }
        lpScanLine += lpbDst->bmWidthBytes;
    }
    _mm_sfence();
    _m_empty();
    return TRUE;
}